package com.ruoyi.common.utils.appsdks;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUserWechat;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author ab785
 * createTime: 2021-6-16.
 * description: 微信相关工具
 */
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "wechat")
public class WechatUtils {

    private static String appId;

    private static String appSecret;

    private static String redirectUrl;

    private static String templateCode;

    private static String appName;

    private static RedisCache redisCache;

    @PostConstruct
    public void init() {
        WechatUtils.redisCache = SpringUtils.getBean(RedisCache.class);
    }

    /**
     * 获取accessToken
     */
    public static String getAccessToken() {
        //先从缓存获取
        String key = "accessToken-wechat";
        String accessToken = redisCache.getCacheObject(key);
        if (accessToken != null) {
            return accessToken;
        }
        //缓存中没有则从请求获取=============================================================================
        Map<String, Object> params = MapBuilder.create(new HashMap<String, Object>())
                .put("grant_type", "client_credential").put("appid", appId).put("secret", appSecret).build();
        String res = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", params);
        JSONObject obj = JSON.parseObject(res);
        //获取失败校验
        if (obj.get("errcode") != null) {
            throw new ServiceException(obj.getString("errmsg"));
        }
        //获取成功,返回accessToken并设置缓存
        accessToken = obj.getString("access_token");
        Integer expiresIn = obj.getInteger("expires_in");
        redisCache.setCacheObject(key, accessToken);
        redisCache.expire(key, expiresIn);
        return accessToken;
    }

    /**
     * 二维码获取
     */
    public static BufferedImage loginQrCode(String state) {
        String urlTpl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={}&redirect_uri={}&response_type=code&scope=snsapi_userinfo&state={}#wechat_redirect";
        String url = StrUtil.format(urlTpl, appId, URLUtil.encode(redirectUrl), state);
        return QrCodeUtil.generate(url, 200, 200);
    }

    /**
     * 根据code获取微信用户信息
     */
    public static SysUserWechat getUserInfoByCode(String code) {
        //第一步,获取openid和access_token
        Map<String, Object> params = MapBuilder.create(new HashMap<String, Object>()).put("appid", appId).put("secret", appSecret).put("code", code).put("grant_type", "authorization_code").build();
        String content = HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token", params);
        //openid,access_token
        JSONObject openJson = JSON.parseObject(content);
        String openid = openJson.getString("openid");
        String accessToken = openJson.getString("access_token");
        //第二部,获取用户信息
        params = MapBuilder.create(new HashMap<String, Object>()).put("access_token", accessToken).put("openid", openid).put("lang", "zh_CN ").build();
        content = HttpUtil.get("https://api.weixin.qq.com/sns/userinfo", params);
        return JSON.parseObject(content, SysUserWechat.class);
    }

    /**
     * 发送验证码
     */
    public static AjaxResult sendVerificationCode(String openid, String code) {
        HttpRequest post = HttpUtil.createPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + getAccessToken());
        //参数设置
        Dict body = Dict.create().set("touser", openid).set("template_id", templateCode).set("topcolor", "#FF0000");
        //内容设置
        Dict data = Dict.create()
                .set("first", Dict.create().set("value", appName).set("color", "#173177"))
                .set("keyword1", Dict.create().set("value", code).set("color", "#ff0000"))
                .set("keyword2", Dict.create().set("value", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).set("color", "#000000"))
                .set("remark", Dict.create().set("value", "验证码在3分钟内有效，请及时输入并登陆！").set("color", "#000000"));
        body.set("data", data);
        post.body(JSON.toJSONString(body));
        //发送请求
        HttpResponse response = post.execute();
        JSONObject res = JSON.parseObject(response.body());
        AjaxResult result = null;
        if (Objects.equals(res.getString("errcode"), "0")) {
            result = AjaxResult.success("发送成功");
        } else {
            result = AjaxResult.error(res.getString("errmsg"));
        }
        return result;
    }

    public void setAppId(String appId) {
        WechatUtils.appId = appId;
    }

    public void setAppSecret(String appSecret) {
        WechatUtils.appSecret = appSecret;
    }

    public void setRedirectUrl(String redirectUrl) {
        WechatUtils.redirectUrl = redirectUrl;
    }

    public void setTemplateCode(String templateCode) {
        WechatUtils.templateCode = templateCode;
    }

    public void setAppName(String appName) {
        WechatUtils.appName = appName;
    }
}
